package org.budo.execute.limit.spring.aop;

import java.lang.reflect.Method;
import java.util.concurrent.Semaphore;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.budo.execute.limit.AbstractExecuteLimitInterceptor;
import org.budo.execute.limit.exception.ExecuteLimitException;

/**
 * @author limingwei
 * 
 * @see com.alibaba.dubbo.rpc.filter.ExecuteLimitFilter
 */
public class ExecuteLimitAopInterceptor extends AbstractExecuteLimitInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Method method = invocation.getMethod();
        Semaphore semaphore = this.getMethodSemaphore(method);

        if (null == semaphore) {
            return invocation.proceed();
        }

        if (semaphore.tryAcquire()) { // 获取到信号量
            try {
                return invocation.proceed(); // 执行方法
            } finally {
                semaphore.release(); // 释放信号量
            }
        }

        // 未获取到信号量
        throw new ExecuteLimitException(method);
    }
}